package cn.mw.cmdb.entity;

import cn.mw.cmdb.param.ImportContextParam;
import cn.mw.microMonitorCommon.entity.cmdb.ModelExportDataInfoParam;
import cn.mw.microMonitorCommon.entity.cmdb.MwImportResultParam;
import cn.mw.cmdb.util.CMDBTool;
import cn.mw.cmdb.view.InstanceInputFieldView;
import cn.mw.components.mongodb.entity.CriteriaOpsType;
import cn.mw.microMonitorCommon.util.IDModelType;
import cn.mw.microMonitorCommon.util.ModuleIDManager;
import cn.mw.microMonitorCommon.util.SpringUtils;
import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Strings;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.util.CollectionUtils;

import java.util.*;

import static cn.mw.cmdb.service.impl.InstanceViewImpl.*;

public class PropertyTypeStruct extends PropertyType<PropertyTypeStruct, Object> {

    public static final String ID = "struct";
    private static Map<String, Map> finalMap = new HashMap();
    public static final String HEADER = "header";
    public static final String structId = "id";
    public static final String structName = "name";
    public static final String typeIdKey = "typeId";
    public static final String structPropertyTypeRef = "propertyTypeRef";
    public static final String DETAIL = "detail";
    public static final String customId = "customId";

    public PropertyTypeStruct() {
        setId(ID);
        setName("结构体");
        setSortNum(6);
    }

    @Override
    public Criteria doCriteria(CriteriaOpsType opsType, String name, Object value) {
        return null;
    }

    @Override
    public CriteriaOpsType getDefaultCriteriaOpsType() {
        return null;
    }

    @Override
    public PropertyTypeStruct newObj() {
        return null;
    }

    @Override
    public Object lookValue(Object val, Map<String, Object> context) {
        if (null == context) {
            return null;
        }
        Map data = new LinkedHashMap();
        data.put(HEADER, context.get(HEADER));
        Object value = null;
        if (val instanceof InstanceInfo) {
            InstanceInfo instanceInfo = (InstanceInfo) val;
            Object key = context.get(CMDBTool.getFieldName(PropertyInfo::getId));
            if (null != key) {
                value = instanceInfo.getValue(key.toString());

            }
        } else {
            value = val;
        }
        data.put(DETAIL, value);
        return data;
    }


    @Override
    public Object readValue(Object val, Map<String, Object> context) {
        Object obj = lookValue(val, context);
        return obj;
    }

    @Override
    public Object selValue(Object val, Map<String, Object> context) {
        Object obj = lookValue(val, context);
        if (obj != null && obj instanceof Map) {
            Object o = ((Map) obj).get(DETAIL);
            return o;
        }
        return null;
    }

    public boolean tableHeaderInfo(Map ms, PropertyInfo propertyInfo, List<String> labelNames, List<String> labelId) {
        //导出表头数据时，表头字段的id和名称不能同时重复
        if ((labelId != null && !labelId.contains(propertyInfo.getId())) && (labelNames != null && !labelNames.contains(ms.get(nameKey)))) {
            ms.put(typeKey, PropertyTypeStruct.ID);
            Map<String, Object> context = propertyInfo.getPropertyTypeRef().getContext();
            List listView = (List) context.get(HEADER);
            List<Map> strucList = new ArrayList<>();
            for (Object obj : listView) {
                Map<String, Object> headerMap = (Map<String, Object>) obj;
                Map structMap = new HashMap();
                String label = strValueConvert(headerMap.get(nameKey));
                String id = strValueConvert(headerMap.get(idKey));
                labelId.add(id);
                String info = "(";
                Map<String, Object> propertyTypeRefMap = (Map<String, Object>) headerMap.get(structPropertyTypeRef);
                PropertyTypeRef propertyTypeRef = JSONObject.parseObject(JSONObject.toJSONString(propertyTypeRefMap), PropertyTypeRef.class);
                String propertyType = strValueConvert(propertyTypeRef.getTypeId());
                PropertyType pType = PropertyTypeManage.getPropertyType(propertyType);
                Object o = pType.tableHeaderTipInfo(propertyTypeRef);
                info += strValueConvert(o) + ")";
                if ("()".equals(info)) {
                    structMap.put(nameKey, label);
                } else {
                    structMap.put(nameKey, label + info);
                }
                strucList.add(structMap);
            }
            ms.put(structDataKey, strucList);
            return true;
        }
        return false;
    }

    /**
     * 导出数据转换
     *
     * @param val
     * @param context
     * @return
     */
    @Override
//    @Override
    public Object exportValue(Object val, Map<String, Object> context) {
        Map map = new HashMap();
        if (val != null && val instanceof List) {
            if (!CollectionUtils.isEmpty((List) val)) {
                List list = (List) val;
                Object o = list.get(0);
                map = (Map) o;
            }
        }
        if (context != null) {
            List list = (List) context.get(HEADER);
            for (Object obj : list) {
                Map m = (Map) obj;
                String id = strValueConvert(m.get(structId));
                Map<String, Object> propertyTypeRefMap = (Map<String, Object>) m.get(structPropertyTypeRef);
                PropertyTypeRef propertyTypeRef = JSONObject.parseObject(JSONObject.toJSONString(propertyTypeRefMap), PropertyTypeRef.class);
                String propertyType = strValueConvert(propertyTypeRef.getTypeId());
                PropertyType pType = PropertyTypeManage.getPropertyType(propertyType);
                Object o = pType.exportValue(map.get(id), context);
                map.put(id, o);
            }
        }
        return map;
    }


    @Override
    public Object getDefaultInputValue(Object val, Map<String, Object> context) {
        List<InstanceInputFieldView> viewList = new ArrayList<>();
        if(context!=null && context.get(HEADER) instanceof  List){
            List list = (List) context.get(HEADER);
            for (Object obj : list) {
                InstanceInputFieldView view = new InstanceInputFieldView();
                Map m = (Map) obj;
                view.setId(strValueConvert(m.get(structId)));
                view.setLabel(strValueConvert(m.get(structName)));
                if (m.get(structPropertyTypeRef) != null) {
                    PropertyTypeRef propertyTypeRef = JSONObject.parseObject(JSONObject.toJSONString(m.get(structPropertyTypeRef)), PropertyTypeRef.class);
                    view.setPropertyType(propertyTypeRef.getTypeId());
                    view.setDefaultValue(propertyTypeRef.getDefaultValue());
                    view.setValue(propertyTypeRef.getContext());
                }
                viewList.add(view);
            }
        }
        Map m = new HashMap();
        m.put(HEADER, viewList);
        return m;
    }

    @Override
    public void refresh() {
        finalMap.clear();
    }

    @Override
    public Object getDataValue(ImportContextParam contextParam) throws Exception {
        MwImportResultParam resultParam = new MwImportResultParam();
        String message = "";
        ModelExportDataInfoParam importParam = contextParam.getParam();
        List<ModelExportDataInfoParam> listInfos = contextParam.getListInfos();
        String structPropertyId = importParam.getStructPropertyId();
        List<Map> listMap = new ArrayList<>();
        Map ms = new HashMap();
        if (finalMap.size() > 0) {
            ms = finalMap.get(structPropertyId);
            if (ms == null) {
                ms = new HashMap();
            }
        }
        finalMap.put(structPropertyId, ms);
        String propertyType = importParam.getPropertyType();
        PropertyType pType = PropertyTypeManage.getPropertyType(propertyType);
        Object dataInfos = pType.getDataValue(contextParam);
        if (dataInfos != null && dataInfos instanceof MwImportResultParam) {
            MwImportResultParam resultInfo = (MwImportResultParam) dataInfos;

            if (resultInfo != null) {
                if (!Strings.isNullOrEmpty(resultInfo.getMessage())) {
                    message = resultInfo.getMessage() + ";";
                }
                if (resultInfo.getCellValue() != null) {
                    ms.put(importParam.getPropertyId(), resultInfo.getCellValue());
                    ModuleIDManager moduleIDManager = SpringUtils.getBean(ModuleIDManager.class);
                    String customId = strValueConvert(moduleIDManager.getID(IDModelType.Model));
                    ms.put(customId, customId);
                }
            }
        }
        resultParam.setMessage(message);
        listMap.add(ms);
        resultParam.setCellValue(listMap);
        return resultParam;
    }
}
